﻿/*********************************************
 创建者：  george
 创建时间：2016-10-31
 功能说明：系统用户管理
 ********************************************/
using com.nm.ApiServer;
using System.ComponentModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using com.nm.Attributes;
using com.nm.Helper;
using com.nm.db.Models.Systems;
using george.Helper;
using com.nm.Security;
using com.nm.ApiServer.Attributes;
using com.nm;
using EntityFramework.Extensions;
using george.Data;

namespace BaseAPI
{
    [Description("用户管理")]
    public class UsersHandler:BaseHandler
    {
        [JsonType]
        [MustAdmin]
        [Description("创建用户")]
        [ReturnType(typeof(int),"0-成功")]
        public ApiResult Create([ParamDescription("输入参数")] model.UserData.CreateData param)
        {
            if (param == null) return Error("对象为空");
            if (string.IsNullOrWhiteSpace(param.UserNo)) return Error("用户编号不能为空");
            if (string.IsNullOrWhiteSpace(param.UserName)) return Error("用户名称不能为空");
            if (string.IsNullOrWhiteSpace(param.LoginAccount)) return Error("登陆账号不能为空");
            if (!param.UserType.IsBetween(0, 3)) return Error("无效的用户类别");
            if (!param.UserStatus.IsBetween(0, 3)) return Error("无效的用户状态");
            if (param.UserNo.Length > 160) return Error("【用户编号】长度超出限制");
            if (param.UserName.Length > 200) return Error("【用户名称】长度超出限制");
            if (param.LoginAccount.Length > 160) return Error("【登陆账号】长度超出限制");
            if (!string.IsNullOrWhiteSpace(param.Address) && param.Address.Length > 200) return Error("【详细地址】长度超出限制");
            if (!string.IsNullOrWhiteSpace(param.Memo) && param.Memo.Length > 50) return Error("【备注】长度超出限制");

            var dc = new SysEntities();
            if(dc.sys_users.Any(t=>t.LoginAccount== param.LoginAccount)) return Error("登陆账号已被占用");
            if(!dc.sys_dept.Any(t=>t.DeptID==param.DeptID)) return Error("无效的部门");
            if (!dc.sys_Post.Any(t => t.PostID == param.PostID)) return Error("无效的岗位");
            if (param.EntryDate == default(DateTime))
                param.EntryDate = DateTime.Now;
            if (param.Avatar != default(Guid))
            {
                var imgList = dc.kmImages.Where(img => img.ID == param.Avatar);
                if (!imgList.Any())
                    return Error("图片错误，请重新上传");
                var qsUser = dc.kmAvatar.Where(t => t.UserID == this.UserId);
                if (qsUser.Any())
                    dc.kmAvatar.Where(t => t.UserID == this.UserId).Delete();
                var yhAvatar = new kmAvatar
                {
                    UserID = this.UserId,
                    ImageID = param.Avatar,
                    IsDefault = false
                };
                dc.kmAvatar.Add(yhAvatar);
            }
            //TODO:用户编号生成规则 UserNo
            var _users = new sys_users
            {
                Address = param.Address,
                Area = param.Area,
                City = param.City,
                Province = param.Province,
                CreateDate = DateTime.Now,
                Creator = this.UserId.ToString(),
                DeptGrade = param.DeptGrade,
                DeptID = param.DeptID,
                Email = param.Email,
                EntryDate = param.EntryDate,
                IsEffective = true,
                IsRemove = false,
                LoginAccount = param.LoginAccount,
                Memo = param.Memo,
                PassWord = MD5.GetPassWord("1qaz2wsx"),
                PostID = param.PostID,
                Sex = param.Sex,
                ShopID = param.ShopID,
                Tel = param.Tel,
                UserName = param.UserName,
                UserNo = param.UserNo,
                UserStatus = param.UserStatus,
                UserType = param.UserType,
                SysType=param.SysType
            };
            dc.sys_users.Add(_users);
          
            try
            {
                dc.SaveChanges();
            }catch(Exception ex)
            {
                return Error(ex.Message);
            }
            return Success(0);
        }

        [JsonType]
        [MustLogin]
        [Description("编辑用户")]
        [ReturnType(typeof(int), "0-成功")]
        public ApiResult Modify([ParamDescription("输入参数")] model.UserData.ModifyData param)
        {
            if (param == null) return Error("对象为空");
            if (string.IsNullOrWhiteSpace(param.UserNo)) return Error("用户编号不能为空");
            if (string.IsNullOrWhiteSpace(param.UserName)) return Error("用户名称不能为空");
            if (string.IsNullOrWhiteSpace(param.LoginAccount)) return Error("登陆账号不能为空");
            if (!param.UserType.IsBetween(0, 3)) return Error("无效的用户类别");
            if (!param.UserStatus.IsBetween(0, 3)) return Error("无效的用户状态");
            if (param.UserNo.Length > 160) return Error("【用户编号】长度超出限制");
            if (param.UserName.Length > 200) return Error("【用户名称】长度超出限制");
            if (param.LoginAccount.Length > 160) return Error("【登陆账号】长度超出限制");
            if (!string.IsNullOrWhiteSpace(param.Address) && param.Address.Length > 200) return Error("【详细地址】长度超出限制");
            if (!string.IsNullOrWhiteSpace(param.Memo) && param.Memo.Length > 50) return Error("【备注】长度超出限制");
            var dc = new SysEntities();
            if (dc.sys_users.Any(t => t.LoginAccount == param.LoginAccount && t.UserID !=param.UserID)) return Error("登陆账号已被占用");
            if (!dc.sys_dept.Any(t => t.DeptID == param.DeptID)) return Error("无效的部门");
            if (!dc.sys_Post.Any(t => t.PostID == param.PostID)) return Error("无效的岗位");
            var user = dc.sys_users.FirstOrDefault(t => t.UserID == param.UserID && t.IsEffective && t.IsRemove==false);
            if (user == null) return Error("未找到用户信息");
            if (param.EntryDate == default(DateTime))
                param.EntryDate = DateTime.Now;
            if (param.Avatar != default(Guid))
            {
                var imgList = dc.kmImages.Where(img =>img.ID==param.Avatar);
                if (!imgList.Any())
                    return Error("图片错误，请重新上传");
                var qsUser = dc.kmAvatar.Where(t => t.UserID ==param.UserID);
                if (qsUser.Any())
                    dc.kmAvatar.Where(t => t.UserID == param.UserID).Delete();
                var yhAvatar = new kmAvatar
                {
                    UserID = param.UserID,
                    ImageID = param.Avatar,
                    IsDefault = false
                };
                dc.kmAvatar.Add(yhAvatar);
            }
            user.Address = param.Address;
            user.Area = param.Area;
            user.City = param.City;
            user.Province = param.Province;
            user.Creator = param.UserID.ToString();
            user.DeptGrade = param.DeptGrade;
            user.DeptID = param.DeptID;
            user.Email = param.Email;
            user.EntryDate = param.EntryDate;
            user.IsEffective = param.IsEffective;
            user.LoginAccount = param.LoginAccount;
            user.Memo = param.Memo;
            user.PostID = param.PostID;
            user.Sex = param.Sex;
            user.ShopID = param.ShopID;
            user.Tel = param.Tel;
            user.UserName = param.UserName;
            user.UserStatus = param.UserStatus;
            user.UserType = param.UserType;
            user.SysType = param.SysType;
            try
            {
                dc.SaveChanges();
            }
            catch (Exception ex)
            {
                return Error(ex.Message);
            }
            return Success(0);
        }

        [MustAdmin]
        [Description("删除用户")]
        [ReturnType(typeof(int), "0-成功")]
        public ApiResult Remove([ParamDescription("用户ID")]int UserID)
        {
            var dc = new SysEntities();
            var user = dc.sys_users.FirstOrDefault(t=>t.UserID==UserID && t.IsRemove==false);
            if (user==null) return Error("未找到用户数据");
            user.IsRemove = true;
            try
            {
                dc.SaveChanges();
            }
            catch
            {
                return Error("删除用户错误");
            }
            return Success(0);
        }

        [MustAdmin]
        [Description("用户密码初始化")]
        [ReturnType(typeof(int), "0-成功")]
        public ApiResult InitPassword([ParamDescription("用户ID")] int UserID)
        {
            var dc = new SysEntities();
            var user = dc.sys_users.FirstOrDefault(t => t.UserID == UserID && t.IsRemove == false);
            if (user == null) return Error("未找到用户数据");
            user.PassWord = MD5.GetPassWord("1qaz2wsx");
            try
            {
                dc.SaveChanges();
            }
            catch
            {
                return Error("用户密码初始化失败");
            }
            return Success(0);
        }

        [MustLogin]
        [Description("获取指定用户信息")]
        [ReturnType(typeof(model.UserData.ListData))]
        public ApiResult GetID([ParamDescription("用户ID")]int UserID)
        {
            var dc = new SysEntities();
            var query = (from u in dc.sys_v_userInfo
                where u.UserID == UserID
                select new
                {
                    u,
                    role = (from r in dc.sys_role
                        join ur in dc.sys_user_role
                        on r.ID equals ur.RoleID
                        where ur.UserID == u.UserID
                        select new {r.RoleType, r.RoleName}).FirstOrDefault(),
                    SysType=(from t in dc.sys_users where t.UserID==UserID select t.SysType).FirstOrDefault(),
                    avatar = (from img in dc.vm_Avatar
                        where img.UserID == UserID
                        orderby img.IsDefault descending
                        select new {img.ImageID, img.Url}).FirstOrDefault()
                });
            var result = query.ToList().Select(o => new model.UserData.ListData
            {
                ImageUrl = o.avatar==null?"": this.GetImageUrl(o.avatar.Url, "http"),
                Avatar= o.avatar?.ImageID ?? default(Guid),
                RoleName = o.role == null ? "" : o.role.RoleName,
                Address = o.u.Address,
                Area = o.u.Area,
                City = o.u.City,
                CreateDate = (DateTime)o.u.CreateDate,
                Creator = o.u.Creator,
                DeptGrade = o.u.DeptGrade,
                DeptID = o.u.DeptID,
                DeptName = o.u.DeptName,
                Email = o.u.Email,
                EntryDate = (DateTime)o.u.EntryDate,
                IsEffective = o.u.IsEffective,
                LoginAccount = o.u.LoginAccount,
                Memo = o.u.Memo,
                PostID = o.u.PostID,
                PostName = o.u.PostName,
                Province = o.u.Province,
                Sex = o.u.Sex,
                ShopID = o.u.ShopID,
                Tel = o.u.Tel,
                UserID = o.u.UserID,
                UserName = o.u.UserName,
                UserNo = o.u.UserNo,
                UserStatus = (int)o.u.UserStatus,
                UserType = (int)o.u.UserType,
                SysType= o.SysType == null ? "" : o.SysType.ToString()
            }).FirstOrDefault();
            return Success(result);
        }

        [MustLogin]
        [Description("获取用户列表")]
        [ReturnType(typeof(PaperData<model.UserData.ListData>))]
        public ApiResult GetList([ParamDescription("部门ID")]int DeptID,
            [ParamDescription("查询条件")] string SearchStr="",
            [ParamDescription("页码")]int Page = 1,
            [ParamDescription("页数")]int Size = 10)
        {
            var dc = new SysEntities();
            var query = (from u in dc.sys_v_userInfo
                where u.DeptID == DeptID
                select new
                {
                    u,
                    role = (from r in dc.sys_role
                        join ur in dc.sys_user_role
                        on r.ID equals ur.RoleID
                        where ur.UserID == u.UserID
                        select new {r.RoleType, r.RoleName}).FirstOrDefault(),
                    avatar = (from img in dc.vm_Avatar
                        where img.UserID ==u.UserID
                        orderby img.IsDefault descending
                        select img.Url).FirstOrDefault()
                });
            if (!string.IsNullOrWhiteSpace(SearchStr))
                query = query.Where(t => t.u.UserName.Contains(SearchStr)
                                         || t.u.UserNo.Contains(SearchStr)
                                         || t.u.Tel.Contains(SearchStr));
            var result = PaperData<model.UserData.ListData>.Create(query.Count(), Size, Page);
            
            result.Items =
                query.OrderByDescending(t => t.u.UserID)
                    .Skip(result.Skip)
                    .Take(result.Limt).ToList()
                    .Select(o => new model.UserData.ListData
                    {
                        ImageUrl = o.avatar == null ? "" : Request.GetImageUrl(o.avatar, "http"),
                        RoleName = o.role == null ? "" : o.role.RoleName,
                        Address = o.u.Address,
                        Area = o.u.Area,
                        City = o.u.City,
                        CreateDate = (DateTime) o.u.CreateDate,
                        Creator = o.u.Creator,
                        DeptGrade = o.u.DeptGrade,
                        DeptID = o.u.DeptID,
                        DeptName = o.u.DeptName,
                        Email = o.u.Email,
                        EntryDate = (DateTime) o.u.EntryDate,
                        IsEffective = o.u.IsEffective,
                        LoginAccount = o.u.LoginAccount,
                        Memo = o.u.Memo,
                        PostID = o.u.PostID,
                        PostName = o.u.PostName,
                        Province = o.u.Province,
                        Sex = o.u.Sex,
                        ShopID = o.u.ShopID,
                        Tel = o.u.Tel,
                        UserID = o.u.UserID,
                        UserName = o.u.UserName,
                        UserNo = o.u.UserNo,
                        UserStatus = (int) o.u.UserStatus,
                        UserType = (int) o.u.UserType
                    }).ToList();
            return Success(result);
        }

        [MustLogin]
        [Description("修改密码")]
        [ReturnType(typeof(int), "0-成功")]
        public ApiResult SetPass(
            [ParamDescription("旧密码（MD5）")]string oldPass,
            [ParamDescription("新密码（MD5）")]string newPass,
            [ParamDescription("重复新密码（MD5）")]string newPassRepeated)
        {
            oldPass = oldPass.ToUpper();
            newPass = newPass.ToUpper();
            newPassRepeated = newPassRepeated.ToUpper();
            if (string.IsNullOrWhiteSpace(oldPass))
                return Error("旧密码不能为空", 4002);
            if (string.IsNullOrWhiteSpace(newPass))
                return Error("新密码不能为空", 4003);
            if (!oldPass.IsMD5Code())
                return Error("旧密码必须是MD5（32位）加密", 4002);
            if (!newPass.IsMD5Code())
                return Error("新密码必须是MD5（32位）加密", 4003);
            if (!newPass.Equals(newPassRepeated))
                return Error("新密码输入不一致", 4004);
            using (var dc = new SysEntities())
            {
                var data = dc.sys_users.FirstOrDefault(item => item.UserID == this.UserId);
                if (data == null)
                    return Error("没有找到相关记录", 4005);
                if (!data.PassWord.Equals(oldPass))
                    return Error("输入的旧密码不正确", 4006);
                if (data.PassWord.Equals(newPass))
                    return Error("新密码不能与旧密码相同", 4007);
                data.PassWord = newPass;
                try
                {
                    dc.SaveChanges();
                    return Success(0);
                }
                catch
                {
                    return Error("修改密码失败", 4008);
                }
            }
        }

        [MustLogin]
        [Description("设置头像")]
        [ReturnType(typeof(int), "0-成功")]
        public ApiResult SetAvater([ParamDescription("图片ID")]Guid imageId)
        {
            var dc = new SysEntities();
            if (imageId != default(Guid))
            {
                var imgList = dc.kmImages.Where(img => imageId == img.ID);
                if (!imgList.Any())
                    return Error("图片错误，请重新上传");
                var qsUser = dc.kmAvatar.Where(t => t.UserID == this.UserId);
                if (qsUser.Any())
                    dc.kmAvatar.Where(t => t.UserID == this.UserId).Delete();
                var yhAvatar = new kmAvatar
                {
                    UserID = this.UserId,
                    ImageID = imageId,
                    IsDefault = false
                };
                dc.kmAvatar.Add(yhAvatar);
                try
                {
                    dc.SaveChanges();
                }
                catch (Exception ex)
                {
                    return Error(ex.Message);
                }
            }
            return Success(0);
        }

        [Description("删除头像")]
        [ReturnType(typeof(int), "0-成功")]
        [MustLogin]
        public ApiResult RemoveAvatar([ParamDescription("图片ID")]Guid imageId)
        {
            var dc = new SysEntities();
            var qsAvatar = dc.kmAvatar.FirstOrDefault(t => t.ImageID == imageId && t.UserID == this.UserId);
            if (qsAvatar == null) return Error("未找到数据");
            var tran = dc.Database.BeginTransaction();
            dc.kmImages.Where(t => t.ID == imageId).Delete();
            dc.kmAvatar.Where(t => t.UserID == this.UserId && t.ImageID == imageId).Delete();
            try
            {
                dc.SaveChanges();
                tran.Commit();
            }
            catch (Exception ex)
            {
                tran.Rollback();
                return Error(ex.Message);
            }
            return Success(0);
        }

        [MustAdmin]
        [Description("模糊查询")]
        [ReturnType(typeof(IList<model.RoleData.UserList>))]
        public ApiResult GetUserMo([ParamDescription("部门ID")]int DeptID, string UserName="")
        {
            var dc = new SysEntities();
            var query = (from a in dc.sys_users where a.DeptID == DeptID && a.IsEffective && a.IsRemove == false select a);
            if (!string.IsNullOrWhiteSpace(UserName))
                query = query.Where(o => o.UserName.Contains(UserName));
            var result = query.Select(o => new model.RoleData.UserList
            {
                UsersID = o.UserID,
                Sex = o.Sex,
                UserName = o.UserName
            }).ToList();
            return Success(result);
        }
    }
}
